package models

import (
	"fmt"
	"ginstudydemo.com/main/dao"
	"github.com/jinzhu/copier"
	"golang.org/x/crypto/bcrypt"
	"strconv"
	"strings"
	"time"
)

// GetUserWithRole 根据用户名查询用户、角色信息、用户密码
func GetUserWithRole(query SysUserUsersLoginBody) (*UserWithRole, error) {
	var result UserWithRole

	err := dao.Db.Debug().Table("sys_user t1").
		Select("t1.id AS userId, t1.username, t1.nickname, t1.password, t1.status, t1.dept_id, GROUP_CONCAT(t3.CODE ORDER BY t3.CODE ASC SEPARATOR ',') AS roles").
		Joins("LEFT JOIN sys_user_role t2 ON t2.user_id = t1.id").
		Joins("LEFT JOIN sys_role t3 ON t3.id = t2.role_id").
		Where("t1.username = ? AND t1.is_deleted = ?", query.Username, 0).
		Group("t1.id, t1.username, t1.nickname, t1.password, t1.status, t1.dept_id").
		Scan(&result).Error

	if err != nil {
		return nil, err
	}
	return &result, nil
}

// GetUserInfoById  根据用户ID从数据库中获取用户信息
func GetUserInfoById(id string) (*SysUserUsersMeSelect, error) {

	var result SysUserUsersMeSelect
	//SELECT id, username, nickname, avatar FROM sys_user
	//WHERE is_deleted = 0 AND (username = ?)
	err := dao.Db.Debug().Table("sys_user").
		Select("id as userId, username, nickname, avatar").
		Where("is_deleted = 0 AND (id = ?)", id).
		Scan(&result).Error

	if err != nil {
		return nil, err
	}
	return &result, nil
}

// GetUserFormInfoById 根据id获取用户表单数据
func GetUserFormInfoById(userId string) (*SysUserUsersFormSelect, error) {
	var result SysUserUsersFormSelect
	//SELECT id, username, nickname, mobile, gender, avatar, email, status, dept_id
	//FROM sys_user
	//WHERE id = ? AND is_deleted = 0

	err := dao.Db.Debug().Table("sys_user").
		Select("id, username, nickname, mobile, gender, avatar, email, status, dept_id ").
		Where("id = ? AND is_deleted = 0", userId).
		Scan(&result).Error

	if err != nil {
		return nil, err
	}
	return &result, nil
}

// GetUserProfile  根据用户ID获取用户信息UserProfile
func GetUserProfile(id string) (*UserProfile, error) {

	var result UserProfile
	//SELECT id, username, nickname, avatar FROM sys_user
	//WHERE is_deleted = 0 AND (username = ?)
	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0 AND (id = ?)", id).
		Scan(&result).Error

	if err != nil {
		return nil, err
	}
	return &result, nil
}

// GetUserPageList 获取用户分页列表相关数据
func GetUserPageList(query SysUserUsersPageListParams, pageParams PaginationParams) ([]SysUserUsersPageListSelect, int64, int, int, error) {

	var users []SysUserUsersPageListSelect
	var total int64
	rootDeptID := 1

	// 创建子查询用于获取部门ID列表
	deptSubQuery := dao.Db.Table("sys_dept").Select("id").Where("id = ? OR FIND_IN_SET(?, tree_path)", rootDeptID, rootDeptID)

	// 主查询用于获取分页数据
	model := dao.Db.Debug().Table("sys_user u").
		Select("u.id, u.username, u.nickname, u.mobile, u.gender, u.avatar, u.status, d.name AS dept_name, GROUP_CONCAT(r.name) AS roleNames, u.create_time").
		Joins("LEFT JOIN sys_dept d ON u.dept_id = d.id").
		Joins("LEFT JOIN sys_user_role sur ON u.id = sur.user_id").
		Joins("LEFT JOIN sys_role r ON sur.role_id = r.id").
		Where("u.is_deleted = 0").
		Where("u.username != ?", "root").
		Where("u.dept_id IN (?)", deptSubQuery).
		Group("u.id")

	// 如果传入了查询条件，则加入模糊查询
	if query.Keywords != "" {
		model = model.Where("u.username LIKE ? OR u.nickname LIKE ? OR u.mobile LIKE ?", "%"+query.Keywords+"%", "%"+query.Keywords+"%", "%"+query.Keywords+"%")
	}

	if query.DeptID != "" {
		model = model.Where("concat(',', concat(d.tree_path, ',', d.id), ',') LIKE concat('%,', ?, ',%')", query.DeptID)
	}

	if query.Status != "" {
		model = model.Where("u.status = ?", query.Status)
	}

	if query.StartTime != "" && query.EndTime != "" {
		model = model.Where("u.create_time >= ? AND u.create_time <= ?", query.StartTime, query.EndTime)
	}

	// 获取总记录数
	if err := model.Count(&total).Error; err != nil {
		return nil, 0, 0, 0, err
	}
	fmt.Println("-------")

	fmt.Println(total)
	fmt.Println("-------")
	// 添加分页条件
	offset := (pageParams.PageNum - 1) * pageParams.PageSize
	model = model.Limit(pageParams.PageSize).Offset(offset)

	// 执行查询获取分页数据
	if err := model.Scan(&users).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	return users, total, pageParams.PageNum, pageParams.PageSize, nil

}

// AddUser 新增用户
func AddUser(user SysUserAddParams) (int64, error) {
	var insertData SysUserAddData

	cpErr := copier.Copy(&insertData, &user)
	if cpErr != nil {
		return insertData.ID, cpErr
	}

	insertData.CreateTime = time.Now()
	insertData.UpdateTime = time.Now()
	// 增加默认密码 123456
	hashPassword, bcryptErr := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost)
	if bcryptErr != nil {
		return 0, bcryptErr
	}
	// 加密后的密码同步到用户信息中
	insertData.Password = string(hashPassword)

	//Create参数需要传入一个指针，所有形参user定义为结构体指针类型
	err := dao.Db.Table("sys_user").Create(&insertData).Error // 通过数据的指针来创建
	return insertData.ID, err
}

// EditUser 修改用户
func EditUser(user SysUserEditParams, userId string) error {
	var editData SysUserEditData

	cpErr := copier.Copy(&editData, &user)
	if cpErr != nil {
		return cpErr
	}

	editData.UpdateTime = time.Now()

	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0").
		Where("id = ?", userId).
		Updates(&editData).Error

	//Create参数需要传入一个指针，所有形参user定义为结构体指针类型
	return err
}

// DelUsers 批量删除（硬删除）
func DelUsers(ids string) error {

	// UPDATE sys_user SET update_time = ?, is_deleted = 1 WHERE id = ? AND is_deleted = 0

	var idsArr []SysUserId
	for _, val := range strings.Split(ids, ",") {
		valNew, _ := strconv.ParseInt(val, 10, 64)
		idsArr = append(idsArr, SysUserId{
			ID: valNew,
		})
	}
	err := dao.Db.Debug().Table("sys_user").Delete(&idsArr).Error
	return err
}

// DelUsersSoft 批量删除（软删除）
func DelUsersSoft(ids string) error {

	// UPDATE sys_user SET update_time = ?, is_deleted = 1 WHERE id = ? AND is_deleted = 0
	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0").
		Where("id IN (?)", ids).
		Updates(map[string]interface{}{"update_time": time.Now(), "is_deleted": 1}).Error
	return err
}

// EditPassword 修改用户密码
func EditPassword(query SysUserPassword, userId string) error {

	hashPassword, bcryptErr := bcrypt.GenerateFromPassword([]byte(query.Password), bcrypt.DefaultCost)
	if bcryptErr != nil {
		return bcryptErr
	}
	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0").
		Where("id = ?", userId).
		Updates(map[string]interface{}{"password": string(hashPassword)}).Error
	return err
}

// EditStatus 修改用户状态
func EditStatus(query SysUserStatus, userId string) error {

	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0").
		Where("id = ?", userId).
		Updates(map[string]interface{}{"status": query.Status}).Error
	return err
}

// EditUserProfile 修改个人中心用户信息
func EditUserProfile(user *UserProfile, userId string) error {
	//var editData UserProfile

	//cpErr := copier.Copy(&editData, &user)
	//if cpErr != nil {
	//	return cpErr
	//}

	//editData.UpdateTime = time.Now()

	err := dao.Db.Debug().Table("sys_user").
		Where("is_deleted = 0").
		Where("id = ?", userId).
		Updates(user).Error

	//Create参数需要传入一个指针，所有形参user定义为结构体指针类型
	return err
}

// --- 旧代码---

// AddUsers 批量增加用户
func AddUsers(users *[]SysUser) ([]uint64, error) {

	fmt.Println(*users)

	//Create参数需要传入一个指针，所有形参user定义为结构体指针类型
	err := dao.Db.Create(users).Error // 通过数据的指针来创建
	var insertIds []uint64
	for _, user := range *users {
		insertIds = append(insertIds, user.Id) // 1,2,3
	}

	return insertIds, err
}

// SaveUser 保存所有字段
func SaveUser(user *SysUser) (uint64, error) {
	//Create参数需要传入一个指针，所有形参user定义为结构体指针类型
	err := dao.Db.Save(user).Error // 通过数据的指针来创建
	return user.Id, err
}
